import * as cc from "cc";
import EventManager from "./EventManager";
import { EventType } from "../GameSpecial/GameEventType";
import { GlobalEnum } from "../GameSpecial/GlobalEnum";
import GameConfig from "../GameSpecial/GameConfig";
import Loader from "./Loader";

//音效管理器
export default class AudioManager {
    /**音效资源 */
    protected static allClips: { [key: string]: cc.AudioClip } = {};

    protected static loopClips: string[] = [];
    protected static bgmAudioSource: cc.AudioSource = null;
    protected static bgmAudioSourceNode: cc.Node = null;
    protected static effectAudioSource: cc.AudioSource = null;
    protected static effectAudioSourceNode: cc.Node = null;

    public static init() {
        if (!this.bgmAudioSourceNode) {
            this.bgmAudioSourceNode = new cc.Node('bgmAudioSourceNode');
            this.bgmAudioSource = this.bgmAudioSourceNode.addComponent(cc.AudioSource);
            this.bgmAudioSource.playOnAwake = false;
        }
        if (!this.effectAudioSourceNode) {
            this.effectAudioSourceNode = new cc.Node('effectAudioSourceNode');
            this.effectAudioSource = this.effectAudioSourceNode.addComponent(cc.AudioSource);
            this.effectAudioSource.playOnAwake = false;
        }
        this.onEvents();
    }
    protected static onEvents() {
        // console.error("未注册音效事件");
        // return;

        EventManager.on(EventType.Common.AudioEvent.playBGM, this.playBGM, this);
        EventManager.on(EventType.Common.AudioEvent.playClickBtn, this.playClickBtn, this);
        EventManager.on(EventType.Common.AudioEvent.playEffect, this.playEffect, this);
        EventManager.on(EventType.Common.AudioEvent.stopEffect, this.stopEffect, this);
        EventManager.on(EventType.Common.AudioEvent.stopBGM, this.stop, this);
        EventManager.on(EventType.Common.AudioEvent.pause, this.pauseBGM, this);
        EventManager.on(EventType.Common.AudioEvent.resume, this.resumeBGM, this);
    }
    protected static onLevelInit() {
        this.loopClips = [];
    }
    protected static playClickBtn() {
        this.playEffect(GlobalEnum.AudioClip.clickBtn);
    }

    protected static playEffect(clip: string, d?: { isLoop: boolean, volume?: number }) {
        if (undefined == d) {
            d = { isLoop: false, volume: 1 };
        } else {
            if (undefined == d.isLoop) {
                d.isLoop = false;
            }
            if (undefined == d.volume) {
                d.volume = 1;
            }
            if (d.isLoop && this.loopClips.indexOf(clip) < 0) {
                this.loopClips.push(clip);
            }
        }

        if (undefined === this.allClips[clip]) {
            Loader.loadBundle("Audio", () => {
                Loader.loadBundleRes("Audio", clip, (res) => {
                    if (!res) {
                        this.allClips[clip] = null;
                        cc.warn("要播放的音效资源未找到：", clip);
                        return;
                    }
                    this.allClips[clip] = res;
                    this._playEffect(clip, d.isLoop, d.volume);
                }, false);
            }, false);
        } else {
            this._playEffect(clip, d.isLoop, d.volume);
        }
    }
    protected static _playEffect(clip: string, isLoop = false, volume = 1) {
        if (!GameConfig.audioConfig.effect) return;
        if (null === this.allClips[clip]) return;
        let c = this.allClips[clip];

        if (!isLoop) {
            this.effectAudioSource.playOneShot(c, volume);
        } else {
            this.effectAudioSource.clip = c;
            this.effectAudioSource.loop = true;
            this.effectAudioSource.play();
        }
    }
    protected static stopEffect(clip: string) {
        if (this.allClips[clip]) {
            this.effectAudioSource.stop();

            let index = this.loopClips.indexOf(clip);
            if (index >= 0) {
                this.loopClips.splice(index, 1);
            }
        }
    }

    protected static curBGM = null;
    protected static playBGM(clip: string, d?: { isLoop: boolean, volume?: number }) {
        let loop = true;
        let volume = 1;
        if (undefined === d) {

        } else if (typeof d === "boolean") {
            loop = d;
        } else if (typeof d === "object") {
            loop = d.isLoop;
            volume = d.volume;
        }
        if (GameConfig.audioConfig.bgm &&
            this.curBGM && this.curBGM == clip && this.allClips[this.curBGM]) {
            let c = this.allClips[this.curBGM];
            this.bgmAudioSource.clip = c;
            this.bgmAudioSource.loop = true;
            if (this.bgmAudioSource.state != 1) {
                this.bgmAudioSource.volume = volume;
                this.bgmAudioSource.play();
            }
            return;
        }
        if (undefined === this.allClips[clip]) {
            Loader.loadBundle("Audio", () => {
                Loader.loadBundleRes("Audio", clip, (res) => {
                    if (!res) {
                        this.allClips[clip] = null;
                        cc.warn("要播放的音效资源未找到：", clip);
                        return;
                    }
                    this.allClips[clip] = res;
                    this._playBGM(clip, loop, volume);
                }, false);
            }, false);
        } else {
            this._playBGM(clip, loop, volume);
        }
    }
    protected static _playBGM(clip: string, loop: boolean, volume: number) {
        if (!GameConfig.audioConfig.bgm) return;
        if (null === this.allClips[clip]) return;
        if (!!this.curBGM) {
            this.bgmAudioSource.stop();
        }
        let c = this.allClips[clip];
        this.bgmAudioSource.clip = c;
        this.bgmAudioSource.loop = true;
        this.curBGM = clip;
        this.bgmAudioSource.volume = volume;
        this.bgmAudioSource.play();
    }
    protected static stop() {
        if (!!this.curBGM) {
            this.bgmAudioSource.stop();
            this.curBGM = null;
        }
    }
    protected static pauseBGM() {
        if (!!this.curBGM) {
            this.bgmAudioSource.pause();
        }
    }
    protected static resumeBGM() {
        if (!!this.curBGM) {
            this.bgmAudioSource.play();
        }
    }
    //----
    protected static onGameOver() {
        for (let i = this.loopClips.length - 1; i >= 0; i--) {
            const e = this.loopClips[i];
            this.stopEffect(e);
        }
    }
}
